export var ary = (fn, n) => (...args) => fn(...args.slice(0, n));

export var call = (key, ...args) => context => context[key](...args);

export var collectInto = fn => (...args) => fn(args);

export var flip = fn => (first, ...rest) => fn(...rest, first);

export var over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));

export var overArgs = (fn, transforms) => (...args) => fn(...args.map((val, i) => transforms[i](val)));

export var pipeAsyncFunctions = (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));

export var promisify = func => (...args) => {
    return new Promise((resolve, reject) =>
        func(...args, (err, result) => (err ? reject(err) : resolve(result)))
    );
}

export var rearg = (fn, indexes) => (...args) => {
    return fn(
        ...args.reduce(
            (acc, val, i) => ((acc[indexes.indexOf(i)] = val), acc),
            Array.from({ length: indexes.length })
        )
    );
}